
#if WIN32

#include <Application.h>
#include <Vertex.h>
#include <Texture2D.h>
#include <Gizmo.h>
#include <Camera.h>
#include <HeightMap.h>
#include <Font.h>
#include <VBO.h>


Application app;

Transform transform;

Gizmo gizmo(5);

Camera camera;

HeightMap hMap("Data\\coastMountain64.raw",64,64,10,0.5f);

Font font;

bool		g_fVBOSupported = false;							// ARB_vertex_buffer_object supported?

CMesh*		g_pMesh = NULL;										// Mesh Data



void InitGL()
{
	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	gluPerspective( 45.0, 640.0 / 480.0, 0.1, 1000.0);
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background
	glClearDepth(1.0f);									// Depth Buffer Setup
	glEnable( GL_TEXTURE_2D );
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
	font.BuildFont(app.mWindow->mHdc);
	//hMap.ReadFile();
	//return TRUE;		
}


int DrawGLScene(GLvoid)									// Here's Where We Do All The Drawing
{
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer
	app.UpdateMousePosition();
	camera.UpdateUserInput(&app.mMouseCurPosition);
	
	camera.UpdateCameraInput(app.mKeys,app.mDeltaTime, app.mIsMouseLButtonDown);

	glMatrixMode( GL_MODELVIEW );

	glEnableClientState( GL_VERTEX_ARRAY );						// Enable Vertex Arrays
	glEnableClientState( GL_TEXTURE_COORD_ARRAY );				// Enable Texture Coord Arrays

	if( g_fVBOSupported )
	{
		glBindBufferARB( GL_ARRAY_BUFFER_ARB, g_pMesh->m_nVBOVertices );
		glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );		// Set The Vertex Pointer To The Vertex Buffer
		glBindBufferARB( GL_ARRAY_BUFFER_ARB, g_pMesh->m_nVBOTexCoords );
		glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL );		// Set The TexCoord Pointer To The TexCoord Buffer
	}

		// Render
	glDrawArrays( GL_TRIANGLES, 0, g_pMesh->m_nVertexCount );	// Draw All Of The Triangles At Once

	// Disable Pointers
	glDisableClientState( GL_VERTEX_ARRAY );					// Disable Vertex Arrays
	glDisableClientState( GL_TEXTURE_COORD_ARRAY );				// Disable Texture Coord Arrays
	
	glLoadIdentity();
	glTranslatef(0.0f,0.0f,-10.0f);	
	font.Print(2,10);
	camera.UpdateViewMatrix();
	gizmo.DrawGizmo();
	//glLoadIdentity();	
	
	//hMap.Draw();
	//glEnd();
	return TRUE;										// Keep Going
}

LRESULT CALLBACK WndProc(HWND inHwnd,UINT inUmsg,WPARAM inWparam, LPARAM inLparam)
{
	return app.WndProc(inHwnd,inUmsg,inWparam, inLparam);
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	MSG msg;
	BOOL done = FALSE;

	app.Initialize(hInstance);

	app.CreateGLWindow(hInstance, WndProc);
	app.ReSizeGLScene(app.mWindow->mWindowRect->right, app.mWindow->mWindowRect->bottom);
	InitGL();

	g_pMesh = new CMesh();

	if(!g_pMesh->LoadHeightMap( "..\\..\\..\\terrain.bmp",					// Load Our Heightmap
								MESH_HEIGHTSCALE,
								MESH_RESOLUTION ) )
								return false;

	g_fVBOSupported = VBO::IsExtensionSupported( "GL_ARB_vertex_buffer_object" );
	if( g_fVBOSupported )
	{
		// Get Pointers To The GL Functions
		glGenBuffersARB = (PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffersARB");
		glBindBufferARB = (PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBufferARB");
		glBufferDataARB = (PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferDataARB");
		glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC) wglGetProcAddress("glDeleteBuffersARB");
		// Load Vertex Data Into The Graphics Card Memory
		g_pMesh->BuildVBOs();									// Build The VBOs
	}

	while(!done)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
			{
				done  = TRUE;
			}
			else
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}else										// If There Are No Messages
		{
			app.UpdateDeltaTime();
			DrawGLScene();
			// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()
			if ( app.mKeys[VK_ESCAPE])	
			{
				done=TRUE;							// ESC or DrawGLScene Signalled A Quit
			}
			else									// Not Time To Quit, Update Screen
			{
				SwapBuffers(app.mWindow->mHdc);					// Swap Buffers (Double Buffering)
			}
		}
	}

	app.KillGLWindow();
	return msg.wParam;
}

#elif

void main()
{
	new v3d();
}

#endif